/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package DataEvaluation;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import rcaller.RCaller;

/**
 *
 * @author Manuel
 */
public class RConnection {

    public RConnection(){
    }

    public ArrayList<String[]> executeCommands(ArrayList<String[]> commands, String dir) {
        ArrayList<String[]> results = new ArrayList<String[]>();
        for(String[] currentCmd : commands){
            try {
                RCaller[] callers= new RCaller[currentCmd.length-1];
                for(int j = 0;j<callers.length;j++){
                    callers[j] = new RCaller();
                }

                //if it is a cor-reg analysis, we have three commands to execute (reg,cor,plot)
                if(callers.length == 3){
                    String[] resultString = new String[6];

                    System.out.println("Running: "+currentCmd[0]);
                    callers[0].RunRCode(currentCmd[0], true, true);
                    String[] corArray = callers[0].RGetAsStringArray("correlation");


                    callers[1].RunRCode(currentCmd[1], true, true);
                    double[] regArray = callers[1].RGetAsDoubleArray("coefficients");

                    System.out.println("Running: "+currentCmd[2]);
                    callers[2].RunRCode(currentCmd[2], true, true);

                    resultString[0] = dir.substring(dir.indexOf("images"))+"/"+currentCmd[currentCmd.length-1];
                    resultString[1] = "α: "+round(regArray[1],6,false)+"&nbsp;β: "+round(regArray[0],6,false);
                    resultString[2] = "p-val: "+round(regArray[7],6,true);
                    resultString[3] = "r^2: "+round(corArray[3],6,false);
                    resultString[4] = "p-val: "+round(corArray[2],6,true);
                    resultString[5] = this.getRequest(currentCmd[0]);
                    results.add(0, resultString);
                }
                //else we have a clustering analysis (less commands)
                else{
                    System.out.println("Running "+currentCmd[0]);
                    callers[0].RunRCode(currentCmd[0], true, true);
                    String[] resultString = new String[2];
                    resultString[0] = dir.substring(dir.indexOf("images"))+"/"+currentCmd[currentCmd.length-1];
                    resultString[1] = this.getRequest(currentCmd[0]);
                    results.add(results.size()-1,resultString);
                }

            } catch (Exception ex) {
                Logger.getLogger(RConnection.class.getName()).log(Level.SEVERE, null, ex);
            }
            
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            Logger.getLogger(RConnection.class.getName()).log(Level.SEVERE, null, ex);
        }
        return results;
    }

    private String round(double d,int decs,boolean cut){
        if(!cut){
            String s = Double.toString(d);
            if(s.toLowerCase().contains("e") && s.contains(".")){
                String es = s.substring(s.toLowerCase().indexOf("e"));
                s= s.substring(0,s.indexOf(".")+decs-2) + es;
                return s;
            }
            if(d >= 0.00001 || d<= -0.00001){
                String format = "#.#####";
                return (new DecimalFormat(format)).format(d);
            }
            return Double.toString(d);
        }
        else if(d < 0.0001)
            return "< 0.0001";
        String format = "#.";
        for(int i = 0;i<decs;i++)
            format+="#";
        DecimalFormat twoDForm = new DecimalFormat(format);
        return twoDForm.format(d);
    }

    private String round(String d,int decs,boolean cut){
        double dval = Double.parseDouble(d);
        return this.round(dval, decs, cut);
    }

    private String stupidRound(String s,int dec){
        String res = s;
        int places = (dec+s.indexOf(".")+1);
        if(s.length()>places)
            res = res.substring(0,places);
        return res;

    }

    private String getRequest(String input) {
        String result ="";
        String pieces = "";
        pieces=input.substring(input.indexOf(";")+1);
        result+=pieces.substring(0,pieces.indexOf("<-")).replaceAll(" ", "")+" -> ";
        pieces=pieces.substring(pieces.indexOf(";")+1);
        result+=(pieces.substring(0,pieces.indexOf("<-")).replaceAll(" ", ""));
        return result;
    }

    public ArrayList<String[]> executeInterMediateCommands(ArrayList<String[]> commands, String dir) {
        ArrayList<String[]> results = new ArrayList<String[]>();
        for(String[] currentCmd : commands){
            try {
                RCaller[] callers= new RCaller[currentCmd.length-1];
                for(int j = 0;j<callers.length;j++){
                    callers[j] = new RCaller();
                }
                    String[] resultString = new String[7];

                    System.out.println("Running: "+currentCmd[0]);
                    callers[0].RunRCode(currentCmd[0], true, true);
                    String[] anArray = callers[0].RGetAsStringArray("analysis");
                    
                    System.out.println("Running: "+currentCmd[1]);
                    callers[1].RunRCode(currentCmd[1], true, true);

                    resultString[0] = dir.substring(dir.indexOf("images"))+"/"+currentCmd[currentCmd.length-1];
                    resultString[1] = "min: "+stupidRound(anArray[0],4);
                    resultString[2] = "µ: "+stupidRound(anArray[3],4);
                    resultString[3] = "max: "+stupidRound(anArray[5],4);
                    resultString[4] = "σ: "+stupidRound(anArray[6],4);
                    resultString[5] = "median: "+stupidRound(anArray[2],4);
                    resultString[6] = currentCmd[2];
                    results.add( resultString);
                

            } catch (Exception ex) {
                Logger.getLogger(RConnection.class.getName()).log(Level.SEVERE, null, ex);
            }

        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            Logger.getLogger(RConnection.class.getName()).log(Level.SEVERE, null, ex);
        }
        return results;
    }
}
